package dept

import (
	"context"
	"net/http"

	"go-zero-admin/apps/system/cmd/api/internal/svc"
	"go-zero-admin/apps/system/cmd/api/internal/types"
	"go-zero-admin/apps/system/cmd/rpc/syspb"
	"go-zero-admin/pkg/constant"
	"go-zero-admin/pkg/ctxdata"

	"github.com/duke-git/lancet/v2/convertor"
	"github.com/duke-git/lancet/v2/strutil"
	"github.com/jinzhu/copier"
	"github.com/zeromicro/go-zero/core/logx"
)

type ListDeptLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
	r      *http.Request
}

func NewListDeptLogic(ctx context.Context, svcCtx *svc.ServiceContext, r *http.Request) *ListDeptLogic {
	return &ListDeptLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
		r:      r,
	}
}

func (l *ListDeptLogic) ListDept(req *types.ListDeptReq) (resp *types.ListDeptResp, err error) {
	listRpc, err := l.svcCtx.DeptRpc.GetDeptList(l.ctx, &syspb.GetDeptListReq{
		DeptName:        req.DeptName,
		Status:          req.Status,
		IsDataScope:     true,
		DataScopeUserId: ctxdata.GetUidFromCtx(l.ctx),
	})
	if err != nil {
		return nil, err
	}
	if len(listRpc.GetList()) == 0 {
		return &types.ListDeptResp{
			DeptList: []*types.SysDept{},
			DeptTree: []*types.SysDeptTree{},
		}, nil
	}

	// 处理数据
	var list []*types.SysDept
	for _, deptRpc := range listRpc.GetList() {
		var dept types.SysDept
		_ = copier.Copy(&dept, deptRpc)
		list = append(list, &dept)
	}

	// 判断最顶级部门的pid
	ancestorsLen := 0
	deptTopPid := constant.DeptFirstPid
	for _, dept := range list {
		ancestors := dept.Ancestors
		parentId := dept.ParentId
		if ancestors == convertor.ToString(constant.DeptFirstPid) {
			deptTopPid = parentId
			break
		}

		pidLen := len(strutil.SplitEx(ancestors, ",", true))
		if ancestorsLen == 0 {
			ancestorsLen = pidLen
			deptTopPid = parentId
		} else if ancestorsLen > pidLen {
			ancestorsLen = pidLen
			deptTopPid = parentId
		}
	}

	return &types.ListDeptResp{
		DeptList: list,
		DeptTree: l.getDeptTree(list, deptTopPid),
	}, nil
}

// 获取树状结构
func (l *ListDeptLogic) getDeptTree(list []*types.SysDept, pid int64) []*types.SysDeptTree {
	var tree []*types.SysDeptTree
	for _, v := range list {
		if v.ParentId != pid {
			continue
		}

		tree = append(tree, &types.SysDeptTree{
			SysDept:  v,
			Children: l.getDeptTree(list, v.DeptId),
		})
	}

	return tree
}
